package com.nuoniu.sibanyun.service.production.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.entity.dto.ChangeWorkerDto;
import com.nuoniu.sibanyun.entity.dto.VProductionWorkDetailSearchDto;
import com.nuoniu.sibanyun.entity.dto.mobile.DispatchSearchDto;
import com.nuoniu.sibanyun.entity.dto.mobile.ProcedureDetailSearchDto;
import com.nuoniu.sibanyun.entity.production.VProductionWorkDetail;
import com.nuoniu.sibanyun.entity.production.VProductionWorkInventoryDetail;
import com.nuoniu.sibanyun.entity.production.VProductionWorkMain;
import com.nuoniu.sibanyun.entity.production.VProductionWorkProcedureDetail;
import com.nuoniu.sibanyun.entity.vo.*;
import com.nuoniu.sibanyun.entity.vo.reportVo.UnFinishProductionWorkDetailSimpleVo;
import com.nuoniu.sibanyun.entity.vo.reportVo.UnFinishProductionWorkMainVo;
import com.nuoniu.sibanyun.entity.vo.reportVo.UnFinishProductionWorkProcedureVo;
import com.nuoniu.sibanyun.mapper.production.VProductionWorkProcedureDetailMapper;
import com.nuoniu.sibanyun.service.erp.IErpAccountService;
import com.nuoniu.sibanyun.service.production.IErpWorkProcedureCardDetailService;
import com.nuoniu.sibanyun.service.production.IVProductionWorkProcedureDetailService;
import com.nuoniu.sibanyun.userThread.DataScope;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 生产加工单——工序明细 服务实现类
 * </p>
 *
 * @author 白强
 * @since 2021-03-20
 */
@Service
public class VProductionWorkProcedureDetailServiceImpl extends ServiceImpl<VProductionWorkProcedureDetailMapper, VProductionWorkProcedureDetail> implements IVProductionWorkProcedureDetailService {

    @Autowired
    private IErpAccountService accountService;
    @Autowired
    private IErpWorkProcedureCardDetailService erpWorkProcedureCardDetailService;

    @Override
    public List<VProductionWorkProcedureDetailVo> listByProductionWorkId(Long productionWorkMainId) {
        Integer currentAccountId = accountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();
        List<VProductionWorkProcedureDetailVo> vProductionWorkDetailSimpleVos = baseMapper.listByProductionWorkId(userInfo.getCompanyId(), currentAccountId, productionWorkMainId);
        return vProductionWorkDetailSimpleVos;
    }

    @Override
    public List<VProductionWorkProcedureDetailVo> listByProductionDispatchId(Long dispatchId) {
        Integer currentAccountId = accountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();
        List<VProductionWorkProcedureDetailVo> vProductionWorkDetailSimpleVos = baseMapper.listByProductionDispatchId(userInfo.getCompanyId(), currentAccountId, dispatchId);
        return vProductionWorkDetailSimpleVos;
    }

    @Override
    public VProductionWorkProcedureDetailVo getVProductionWorkProcedureDetailVo(Integer id) {
        Integer currentAccountId = accountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();
        VProductionWorkProcedureDetailVo vProductionWorkProcedureDetailVo = baseMapper.getVProductionWorkProcedureDetailVo(userInfo.getCompanyId(), currentAccountId, id);
        return vProductionWorkProcedureDetailVo;
    }

    @Override
    public VProductionWorkProcedureDetailVo getVProductionWorkProcedureDetailVoByProcedureId(Integer detailId,Integer procedureId) {
        Integer currentAccountId = accountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();
        VProductionWorkProcedureDetailVo vProductionWorkProcedureDetailVo = baseMapper.getVProductionWorkProcedureDetailVoByProcedureId(userInfo.getCompanyId(), currentAccountId, detailId, procedureId);
        return vProductionWorkProcedureDetailVo;
    }

    @Override
    public VProductionWorkProcedureDetailVo getVProductionWorkProcedureDetailVoByOrder(Integer detailId, Integer order) {
        Integer currentAccountId = accountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();
        VProductionWorkProcedureDetailVo vProductionWorkProcedureDetailVo = baseMapper.getVProductionWorkProcedureDetailVoByOrder( userInfo.getCompanyId(), currentAccountId, detailId, order);
        return vProductionWorkProcedureDetailVo;
    }

    @Override
    public BigDecimal getTotalCumUnqualifiedQuantityBeginOrder(Integer detailId, Integer order) {
        Integer currentAccountId = accountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();
        BigDecimal totalCumUnqualifiedQuantity = baseMapper.getTotalCumUnqualifiedQuantityBeginOrder(userInfo.getCompanyId(), currentAccountId, detailId, order);
        return totalCumUnqualifiedQuantity;
    }

    @Override
    public BigDecimal getLastProcedureCumQualifiedQuantityBeginOrder(Integer productionDispatchId, Integer order) {
        Integer currentAccountId = accountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();
        BigDecimal lastProcedureCumQualifiedQuantityBeginOrder = baseMapper.getLastProcedureCumQualifiedQuantityBeginOrder(userInfo.getCompanyId(), currentAccountId, productionDispatchId, order);
        return lastProcedureCumQualifiedQuantityBeginOrder;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void batchUpdateStatus(Integer productionDispatchId, Integer processRouteDetailId, Integer status) {
        UpdateWrapper<VProductionWorkProcedureDetail>  updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("production_dispatch_id",productionDispatchId);
        updateWrapper.eq("process_route_detail_id",processRouteDetailId);
        updateWrapper.ne("status",1);
        updateWrapper.set("status",status);
        update(updateWrapper);
    }

    @Override
    public boolean isLastProcedureFinished(Integer productionDispatchId, Integer order) {
        Integer currentAccountId = accountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();
        boolean lastProcedureFinished = baseMapper.isLastProcedureFinished(userInfo.getCompanyId(), currentAccountId, productionDispatchId, order);
        return lastProcedureFinished;
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void changeWorkId(ChangeWorkerDto changeWorkerDto) {
        Long id = changeWorkerDto.getId();
        Integer workerId = changeWorkerDto.getWorkerId();
        String workerName = changeWorkerDto.getWorkerName();
        String workerNo = changeWorkerDto.getWorkerNo();
        LocalDate startDate = changeWorkerDto.getStartDate();
        VProductionWorkProcedureDetail oldDetail = getById(id);
        Integer status = oldDetail.getStatus();
        if (1 == status )throw new NuoNiuException("工序派工任务已经中止");
        if (10 == status )throw new NuoNiuException("工序派工任务已经完成");
        oldDetail.setStatus(1);
        updateById(oldDetail);

        oldDetail.setId(null);
        oldDetail.setWorkerId(workerId);
        oldDetail.setWorkerName(workerName);
        oldDetail.setWorkerNo(workerNo);
        oldDetail.setStartDate(startDate);
        oldDetail.setStatus(0);
        save(oldDetail);
    }

    @Override
    public VProductionWorkProcedureDetailDispatchVo getUnFinishProcedureDetailDispatchVo(VProductionWorkDetailSearchDto productionDispatchMainSearchDto) {
        VProductionWorkProcedureDetailDispatchVo productionWorkProcedureDetailDispatchVo = new VProductionWorkProcedureDetailDispatchVo();
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = accountService.getCurrentAccountId();
        List<VProductionDispatchSimpleVo> productionDispatchSimpleVos = baseMapper.listUnFinishProductionDispatchSimpleVo(userInfo.getCompanyId(), currentAccountId, productionDispatchMainSearchDto);
        productionWorkProcedureDetailDispatchVo.setProductionDispatchSimpleVoList(productionDispatchSimpleVos);
        List<VProcedureDetailSimpleVo> procedureDetailSimpleVos = baseMapper.listUnFinishProcedureDetailSimpleVo(userInfo.getCompanyId(), currentAccountId, productionDispatchMainSearchDto);
        productionWorkProcedureDetailDispatchVo.setProcedureDetailSimpleVoList(procedureDetailSimpleVos);
        return productionWorkProcedureDetailDispatchVo;
    }

    /**
     * 查询 未完成产品明细 和 工序明细（分 数据权限 ）
     * @param productionWorkDetailSearchDto
     * @return
     */
    @Override
    public UnFinishProductionWorkMainVo getUnFinishProductionWorkVo(VProductionWorkDetailSearchDto productionWorkDetailSearchDto) {
        UnFinishProductionWorkMainVo unFinishProductionWorkMainVo = new UnFinishProductionWorkMainVo();
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = accountService.getCurrentAccountId();
        Integer companyId = userInfo.getCompanyId();
        List<UnFinishProductionWorkDetailSimpleVo> unFinishProductionWorkDetailSimpleVos = baseMapper.listUnFinishProductionWorkDetailSimpleVo(companyId, currentAccountId, productionWorkDetailSearchDto);
        unFinishProductionWorkMainVo.setUnFinishProductionWorkDetailSimpleVoList(unFinishProductionWorkDetailSimpleVos);
        List<UnFinishProductionWorkProcedureVo> unFinishProductionWorkProcedureVos = baseMapper.listUnFinishProductionWorkProcedureVo(companyId, currentAccountId, productionWorkDetailSearchDto);
        unFinishProductionWorkMainVo.setUnFinishProductionWorkProcedureVoList(unFinishProductionWorkProcedureVos);
        return unFinishProductionWorkMainVo;
    }


    @Override
    public Page<VProductionDispatchSimpleVo> pagePersonalDispatch(Page page, DispatchSearchDto dispatchSearchDto) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = accountService.getCurrentAccountId();
        DataScope dataScope = userInfo.getDataScope();
        //最大数据权限类型
        String officeIds = dataScope.getOfficeIds();
        String userIds = userInfo.getUserId() + "";
        Page<VProductionDispatchSimpleVo> vProductionDispatchSimpleVoPage = baseMapper.pagePersonalDispatch(page, userInfo.getCompanyId(), currentAccountId, officeIds, userIds, dispatchSearchDto);
        return vProductionDispatchSimpleVoPage;
    }

    /**
     * 获取未完成的派工工序任务单（移动端）
     * @param page
     * @param procedureDetailSearchDto
     * @return
     */
    @Override
    public Page<VProcedureDetailSimpleVo> pageVProcedureDetailSimpleVo(Page page, ProcedureDetailSearchDto procedureDetailSearchDto) {

        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = accountService.getCurrentAccountId();
        DataScope dataScope = userInfo.getDataScope();
        //最大数据权限类型
        String officeIds = dataScope.getOfficeIds();
        String userIds = userInfo.getUserId() + "";
        Page<VProcedureDetailSimpleVo> vProcedureDetailSimpleVoPage = baseMapper.pageVProcedureDetailSimpleVo(page, userInfo.getCompanyId(), currentAccountId, officeIds, userIds, procedureDetailSearchDto);
        return vProcedureDetailSimpleVoPage;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void batchSave(VProductionWorkMain productionWorkMain, List<Long> detailIds) {
        //查询
        /**  校验 删除的工序明细 是否汇报 */
        boolean b = erpWorkProcedureCardDetailService.checkWorkReport(productionWorkMain.getId());
        if(b)throw new NuoNiuException("工序已经汇报，不能修改");
        Integer currentAccountId = accountService.getCurrentAccountId();
        Long mainId = productionWorkMain.getId();
        UserInfo userInfo = UserThreadLocal.get();


        List<VProductionWorkProcedureDetail> newVProductionWorkProcedureDetailList = new ArrayList<>();
        List<VProductionWorkDetail> orderDetailList = productionWorkMain.getOrderDetailList();
        Set<Long> notDeleteProcedureDetailIds = new HashSet<>();
        orderDetailList.forEach(detail->{
            Long detailId = detail.getId();
            List<VProductionWorkProcedureDetail> productionWorkProcedureDetailList = detail.getProductionWorkProcedureDetailList();
            if(null == productionWorkProcedureDetailList || productionWorkProcedureDetailList.size() == 0)throw new NuoNiuException("产品明细："+detail.getInventoryName() + " 的工序明细 不能为空");
            //删除 剩余产品明细中更换的 材料明细
            if(detailIds.contains(detailId)){
               productionWorkProcedureDetailList.forEach(procedureDetail -> {
                   if(null != procedureDetail.getId()){
                       notDeleteProcedureDetailIds.add(procedureDetail.getId());
                   }
               });
            }
            productionWorkProcedureDetailList.forEach(workProcedureDetail->{
                if( null == workProcedureDetail.getId()){
                    workProcedureDetail.setStatus(0);
                }
                workProcedureDetail.setCompanyId(detail.getCompanyId());
                workProcedureDetail.setAccountId(detail.getAccountId());
                workProcedureDetail.setProductionWorkMainId(mainId.intValue());
                workProcedureDetail.setProductionWorkDetailId(detail.getId().intValue());
                newVProductionWorkProcedureDetailList.add(workProcedureDetail);
            });
        });
        //1.根据 加工单 产品明细的ID 删除 材料明细
        if (null != detailIds && detailIds.size() > 0){
            QueryWrapper<VProductionWorkProcedureDetail> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("company_id",userInfo.getCompanyId());
            queryWrapper.eq("account_id",currentAccountId);
            queryWrapper.eq("production_work_main_id",mainId);
            if(notDeleteProcedureDetailIds.size() > 0){
                queryWrapper.and(wrapper->wrapper.notIn("production_work_detail_id",detailIds)
                        .or(wrapper2->wrapper2.in("production_work_detail_id",detailIds).and(wrapper3->wrapper3.notIn("id",notDeleteProcedureDetailIds))));
            }
            remove(queryWrapper);
        }
        if (newVProductionWorkProcedureDetailList.size() > 0){
            saveOrUpdateBatch(newVProductionWorkProcedureDetailList);
        }


    }

    @Override
    public void deleteFromMainId(Long mainId) {
        boolean b = erpWorkProcedureCardDetailService.checkWorkReport(mainId);
        if(b)throw new NuoNiuException("工序已经汇报，不能删除");
        Integer currentAccountId = accountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();
        QueryWrapper<VProductionWorkProcedureDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("company_id",userInfo.getCompanyId());
        queryWrapper.eq("account_id",currentAccountId);
        queryWrapper.eq("production_work_main_id",mainId);
        remove(queryWrapper);
    }


}
